package com.echat.messagesender.sender.email;

import com.echat.messagesender.sender.bean.EchatSendEmailInfo;
import com.echat.messagesender.sender.bean.SendResult;
import com.echat.messagesender.sender.constant.Constants;
import com.echat.messagesender.sender.email.impl.CommonsEmailSender;
import com.echat.messagesender.sender.model.EmailTemplate;
import com.echat.messagesender.sender.model.EmailTemplateMapping;
import com.echat.messagesender.sender.service.SendLogService;
import com.echat.messagesender.sender.service.TemplateService;
import com.echat.messagesender.sender.util.JsonUtil;
import com.echat.messagesender.sender.util.TemplateUtil;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

/**
 * Created by chenmohan on 2018/08/14
 *
 * @description
 */
@Log4j2
public class EmailSenderManager {

    ExecutorService emailProcessor = Executors.newFixedThreadPool(10);

    /** 按照sort字段排序的list */
    @Setter
    @Getter
    private List<EmailSender> emailSenderList;

    /** Apche Email Sender 是第一个元素的List */
    private List<EmailSender> emailSenderList2;

    @Getter
    @Setter
    private Map<Long,EmailSender> emailSenderMap;

    @Autowired
    SendLogService sendLogService;

    @Autowired
    TemplateService templateService;

    /**
     * 发送邮件
     *
     * @param info
     */
    public boolean sendEmail(EchatSendEmailInfo info) {
        return doSendEmail(info);
    }

    /**
     * 发送邮件
     *
     * @param info EchatSendEmailInfo
     */
    private boolean doSendEmail(EchatSendEmailInfo info) {
        //保存发送日志
        Future<Long> emailIdFutrue = emailProcessor.submit(() -> sendLogService.addFullEmailSendLog(info));
        StringBuilder sb = new StringBuilder();
        List<EmailSender> senders = this.emailSenderList;
            //如果有抄送信息，那么首先使用apacheEmail发送邮件，其他的第三方平台服务不支持邮件的抄送功能
        if(info.getBccReceivers() != null || info.getCcReceivers() != null || info.getReplyEmail() != null){
            senders = orderApacheEmail(this.emailSenderList);
        }
            //如果指定了平台账号,那么就使用该账号发送邮件
        if(info.getPlatformAccountId()!=null){
            EmailSender sender = getEmailSenderMap().get(info.getPlatformAccountId());
            senders = Arrays.asList(new EmailSender[]{sender});
        }
        for (EmailSender sender : senders) {
            String platformName = sender.getPlatformName();
            sb.append(sb.length() == 0 ? platformName : Constants.RIGHT_ARRAW + platformName);
            if (sendEmail0(sender, info)) {
                //发送成功则直接返回
                Long emailId = getEmailIdFutrue(emailIdFutrue);
                if(emailId == null){
                    log.warn("【邮件】{}发送邮件[{}]失败", platformName ,info.toString());
                    continue;
                }
                SendResult sendResult = SendResult.builder()
                        .id(emailId)
                        .sendPlatformId(sender.getPlatformAccountId())
                        .sendResult(true)
                        .memo(sb.toString()).build();
                emailProcessor.submit(() -> sendLogService.setEmailSendResult(sendResult));
                log.info("【邮件】emailId[" + emailId + "],由"+platformName+"发送成功!");
                return true;
            }else{
                log.warn("【邮件】{}发送邮件[{}]失败", platformName ,info.toString());
            }
        }
        log.warn("【邮件】邮件[id={}]发送完全失败", info.toString());
        return false;
    }

    private  boolean sendEmail0(EmailSender sender, EchatSendEmailInfo info) {
        ifTemplateIdNotNullAndProcessTemplate(info,sender);
        return sender.sendEmail(info.getReceivers(), info.getTitle(), info.getContent(), info.getCcReceivers(), info.getBccReceivers(), info.getReplyEmail());
    }

    private <T> T getEmailIdFutrue(Future<T> future) {
        try {
            return future.get();
        } catch (InterruptedException e) {
            log.error(e.getCause() );
        } catch (ExecutionException e) {
            log.error(e.getCause());
        }
        return null;
    }

    /**
     * 如果EchatSendEmailInfo中存在模板id，那么处理模板邮件文本
     * @param info
     * @param sender
     */
    private void ifTemplateIdNotNullAndProcessTemplate(EchatSendEmailInfo info , EmailSender sender){
        if(info.getTemplateId()==null){
            return;
        }
        Long templateId = Long.valueOf(info.getTemplateId());
        //判断是否是有对应的平台模板id
        EmailTemplateMapping mapping = templateService.getEmailTemplateMappingId(templateId, sender.getPlatformId());
        if(mapping != null){
            info.setTemplateId(mapping.getPlatformTemplateId());
            return;
        }
        EmailTemplate template = templateService.getEmailTemplateById(templateId);
        if(info.getContent() == null || template == null){
            return;
        }
        Map<String, String> paramMap = JsonUtil.toMap(info.getVars());
        String translateContent = TemplateUtil.translate(template.getContent(), paramMap);
        info.setContent(translateContent);
    }

    private List<EmailSender> orderApacheEmail(List<EmailSender> emailSenderList){
        if(emailSenderList2 != null){
            return emailSenderList2;
        }
        EmailSender apacheEmailSender = null;
        for(EmailSender sender : emailSenderList){
            if(sender instanceof CommonsEmailSender){
                apacheEmailSender = sender;
            }
        }
        ArrayList<EmailSender> emailSenders = new ArrayList<>(emailSenderList);
        emailSenderList.remove(apacheEmailSender);
        emailSenderList.add(0,apacheEmailSender);
        emailSenderList2 = emailSenderList;
        return emailSenderList2;
    }

}
